#include    "InvocableUserCommandTree.h"

// File [alfs/gui/InvocableUserCommandTree.cpp].
//
// InvocableUserCommandTree
//
// An InvocableUserCommandTree is a tree of InvocableUserCommand instances.  For
// example, it can represent a hierarchical menu structure.
//
// (c) copyright Alf P. Steinbach 2008.
// Use, modification and distribution are subject to the "New BSD License"
// as listed at <url: http://www.opensource.org/licenses/bsd-license.php>.

namespace alfs{

#   define  ThisClass       InvocableUserCommandTree
#   define  ThisClassName   ALFS_STRINGIFIED( ThisClass )

    ThisClass::NodePtr::NodePtr( InvocableUserCommand::Ptr command )
        : myCommand( command )
    {
        assertInvariant();
    }

    ThisClass::NodePtr::NodePtr( ThisClass::Ptr tree )
        : myTree( tree )
    {
        assertInvariant();
    }

    bool ThisClass::NodePtr::isTree() const    { return myCommand.isVoid(); }
    bool ThisClass::NodePtr::isCommand() const { return myTree.isVoid(); }

    ThisClass::Ptr ThisClass::NodePtr::tree() const
    {
        (isTree()) || throwX( ThisClassName "::NodePtr::tree: this node is a not a tree." );
        return myTree;
    }

    InvocableUserCommand::Ptr ThisClass::NodePtr::command() const
    {
        (isCommand()) || throwX( ThisClassName "::NodePtr::command: this node is a tree." );
        return myCommand;
    }

    ThisClass::~ThisClass()
    {}

    ThisClass::ThisClass( std::wstring const& defaultTitle )
        : myDefaultText( defaultTitle )
    {
        assertInvariant();
    }

    std::wstring ThisClass::text() const
    {
        return myDefaultText;
    }

    ThisClass::Ptr ThisClass::addChild( ThisClass::Ptr tree )
    {
        myNodes.push_back( NodePtr( tree ) );
        return tree;
    }

    InvocableUserCommand::Ptr ThisClass::addChild( InvocableUserCommand::Ptr command )
    {
        myNodes.push_back( NodePtr( command ) );
        return command;
    }

    std::size_t ThisClass::nChildren() const
    {
        return myNodes.size();
    }

    ThisClass::NodePtr const& ThisClass::childAt( std::size_t i ) const
    {
        return myNodes.at( i );
    }

    ThisClass::Iterator ThisClass::begin() const
    {
        return myNodes.begin();
    }

    ThisClass::Iterator ThisClass::end() const
    {
        return myNodes.end();
    }

#   undef   ThisClassName
#   undef   ThisClass
}  // alfs
